package org.jeecg.modules.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.modules.dto.InTaskDto;
import org.jeecg.modules.dto.OutTaskRunningDto;
import org.jeecg.modules.service.IActTaskService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ActTaskServiceImpl implements IActTaskService {

  @Autowired
  private TaskService taskService;
  @Autowired
  public RuntimeService runtimeService;
  @Autowired
  public RepositoryService repositoryService;

  @Autowired
  private ISysBaseAPI sysBaseAPI;

  @Override
  public IPage<OutTaskRunningDto> listTodoTask(InTaskDto inTaskDto, Integer pageNo, Integer pageSize,
      HttpServletRequest request) {
    String userName = JwtUtil.getUserNameByToken(request);
    log.info("当前登录用户名：{}", userName);
    List<String> roleIds = sysBaseAPI.getRoleIdsByUsername(userName);
    log.info("当前登录用户角色：{}", roleIds);
    // =============== 已经签收的任务 ===============
    TaskQuery todoTaskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userName)
        // .or().taskCandidateGroupIn(roleIds)
        .active().includeProcessVariables().orderByTaskCreateTime().desc();
    // 设置查询条件
    if (StringUtils.isNotBlank(inTaskDto.getProcessDefKey())) {
      todoTaskQuery.processDefinitionKey(inTaskDto.getProcessDefKey());
    }
    if (inTaskDto.getBeginDate() != null) {
      todoTaskQuery.taskCreatedAfter(inTaskDto.getBeginDate());
    }
    if (inTaskDto.getEndDate() != null) {
      todoTaskQuery.taskCreatedBefore(inTaskDto.getEndDate());
    }

    Page<OutTaskRunningDto> page = new Page<OutTaskRunningDto>(pageNo, pageSize);
    // 查询列表
    List<Task> todoList = todoTaskQuery.listPage((int) page.getCurrent() - 1, (int) page.getSize());

    log.info(">>>>> {}", todoList);

    page.setTotal(todoTaskQuery.count());
    page.setRecords(convertTaskList(todoList));
    return page;
  }

  private List<OutTaskRunningDto> convertTaskList(List<Task> todoList) {
    return Optional.ofNullable(todoList)
        .orElse(new ArrayList<>())
        .stream()
        .map(task -> {
          TaskEntity taskEntity = (TaskEntity) task;
          log.info(">>>> taskEntity = {}", taskEntity);
          OutTaskRunningDto outTaskRunningDto = new OutTaskRunningDto();
          // ExecutionEntity execution = taskEntity.getExecution();
          // log.info(">>>> execution = {}", execution);
          // ExecutionEntity processInstance = taskEntity.getProcessInstance();

          BeanUtils.copyProperties(task, outTaskRunningDto);
          outTaskRunningDto.setTaskName(task.getName());

          ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
              .processInstanceId(task.getProcessInstanceId()).singleResult();
          log.info(">>>> processInstance = {}", processInstance);

          ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
              .processDefinitionId(task.getProcessDefinitionId())
              .singleResult();
          log.info(">>>> processDefinition = {}", processDefinition);

          outTaskRunningDto.setProcessVariables(task.getProcessVariables());
          // outTaskRunningDto.setExecutionName(execution.getName());
          // outTaskRunningDto.setProcessName(processInstance.getProcessInstance().getName());
          return outTaskRunningDto;
        })
        .collect(Collectors.toList());
  }
}
